package com.zyd.service.power.impl;

import com.alibaba.fastjson.JSON;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.collect.Maps;
import com.sun.org.apache.bcel.internal.generic.RETURN;
import com.zyd.context.HeaderContext;
import com.zyd.io.model.*;
import com.zyd.io.vo.city.CityVO;
import com.zyd.io.vo.city.CountryVO;
import com.zyd.io.vo.city.ProvinceVO;
import com.zyd.io.vo.power.MenuAreaVO;
import com.zyd.io.vo.power.SavePowerVO;
import com.zyd.mappers.RolePowerEntityMapper;
import com.zyd.mappers.UserEntityMapper;
import com.zyd.service.city.CityService;
import com.zyd.service.power.PowerService;
import com.zyd.util.SqlUtils;
import com.zyd.util.ToolUtils;
import com.zyd.util.UUIDUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Component;

import java.awt.*;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;

@Component
public class PowerServiceImpl implements PowerService {

    private static final Logger LOGGER = LoggerFactory.getLogger(PowerServiceImpl.class);

    private static final Splitter SPLITTER = Splitter.on(',').trimResults().omitEmptyStrings();

    private static final Joiner JOINER = Joiner.on(',').skipNulls();

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private CityService cityService;

    @Autowired
    private RolePowerEntityMapper mapper;

    @Autowired
    private UserEntityMapper userMapper;

    @Override
    public Map<String, Object> queryPowsersByRoleId(String roleId) {
        StringBuilder sql = new StringBuilder();
        sql.append("select * from zydzn_menu where dr = 0 and isfloder = \'Y\' order by sortno");

        List<MenuEntity> menus = doFindMenus(sql.toString());

        for (MenuEntity menu : menus) {
            sql = new StringBuilder();
            sql.append("select * from zydzn_menu where dr = 0 and isfloder = \'N\' and parentid = \'" +
                    menu.getId() + "\' order by sortno");

            List<MenuEntity> childMenus = doFindMenus(sql.toString());
            menu.setChildren(childMenus);

            for (MenuEntity childMenu : childMenus) {
                if (childMenu.getIshavearea().equals("Y")) {
                    childMenu.setAreas(cityService.findCitys());
                }

                sql = new StringBuilder();
                sql.append("select * from zydzn_menu where dr = 0 and isfloder = \'N\' and isoperate = \'Y\' and parentid = \'" +
                        childMenu.getId() + "\' order by sortno");
                List<MenuEntity> opMenus = doFindMenus(sql.toString());
                for (MenuEntity entity : opMenus) {
                    if (entity.getIshavearea().equals("Y")) {
                        entity.setAreas(cityService.findCitys());
                    }
                }
                childMenu.setChildren(opMenus);
            }
        }

        Map<String, Object> ret = Maps.newHashMap();
        ret.put("menus", menus);
        doSetPower(menus, findRolePowers(roleId));
        return ret;
    }

    @Override
    public void savePowers(SavePowerVO savePowerVO) {
        RolePowerEntityExample example = new RolePowerEntityExample();
        example.or().andRoleidEqualTo(savePowerVO.getRoleid());
        mapper.deleteByExample(example);

        for (MenuAreaVO menuAreaVO :savePowerVO.getMenus()) {
            RolePowerEntity entity = new RolePowerEntity();
            entity.setId(UUIDUtil.getUUid());
            entity.setDr(0);
            entity.setTs(ToolUtils.getNowTime());

            entity.setRoleid(savePowerVO.getRoleid());
            entity.setMenuid(menuAreaVO.getMenuid());
            entity.setArea(JOINER.join(menuAreaVO.getAreaIds()));
            mapper.insertSelective(entity);
        }

    }

    @Override
    public Map<String, Object> queryPowsersByUserId(String userid) {
        UserEntityKey key = new UserEntityKey();
        key.setId(userid);
        UserEntity userEntity = userMapper.selectByPrimaryKey(key);
        return queryPowsersByRoleId(userEntity.getUsertype());
    }

    @Override
    public RolePowerEntity queryPowerListByUserId(String userid, String menuid) {
        if (ToolUtils.isEmpty(userid) || ToolUtils.isEmpty(menuid)) {
            return null;
        }
        UserEntityKey key = new UserEntityKey();
        key.setId(userid);
        UserEntity entity = userMapper.selectByPrimaryKey(key);

        RolePowerEntityExample example = new RolePowerEntityExample();
        example.or().andRoleidEqualTo(entity.getUsertype()).andMenuidEqualTo(menuid).andDrEqualTo(0);
        return mapper.selectByExample(example).get(0);
    }

    private List<MenuEntity> doFindMenus(String sql) {
        List<MenuEntity> menus = jdbcTemplate.query(sql.toString(), new RowMapper<MenuEntity>() {
            @Override
            public MenuEntity mapRow(ResultSet rs, int rowNum) throws SQLException {
                MenuEntity menuEntity = SqlUtils.mappingToBean(rs, MenuEntity.class);
                return menuEntity;
            }
        });
        return menus;
    }

    private List<RolePowerEntity> findRolePowers(String roleid) {
        RolePowerEntityExample example = new RolePowerEntityExample();
        example.or().andRoleidEqualTo(roleid);

        List<RolePowerEntity> powers = mapper.selectByExample(example);
        return powers;
    }

    private void doSetPower(List<MenuEntity> menus, List<RolePowerEntity> powers) {
        for (RolePowerEntity power : powers) {
            MenuEntity menu = getMenu(power.getMenuid(), menus);
            menu.setHasPower(1);

            if (menu.getIshavearea().equals("Y")) {
                if (power.getArea() != null && !power.getArea().isEmpty()) {
                    List<String> areas = SPLITTER.splitToList(power.getArea());
                    doSetArea(menu, areas);
                }
            }
        }
    }

    private MenuEntity getMenu(String menuid, List<MenuEntity> menus) {
        if (menus == null || menus.isEmpty()) {
            return null;
        }
        MenuEntity ret = null;
        for (MenuEntity menu : menus) {
            if (menu.getId().equals(menuid)) {
                ret = menu;
                break;
            } else {
                ret = getMenu(menuid, menu.getChildren());
                if (ret != null) {
                    break;
                }
            }
        }

        return ret;
    }

    private void doSetArea(MenuEntity entity, List<String> areaid) {
        List<ProvinceVO> areas = entity.getAreas();
        for (ProvinceVO provinceVO : areas) {
            for (CityVO cityVO : provinceVO.getCitys()) {
                for (CountryVO countryVO : cityVO.getCountrys()) {
                    LOGGER.info("areaid:" + JSON.toJSONString(areaid )+ ",区县ID:" + countryVO.getId());
                    if (areaid.contains(countryVO.getId())) {
                        LOGGER.info("设置地区成功,id:" + countryVO.getId());
                        countryVO.setHasPower(1);
                    }
                }
            }
        }
    }
//获取用户权限地区
    public String getLocation(){
//        根据userid 找到用户权限地址area
        String sql ="select area from zydzn_power where roleid=(select usertype from zydzn_users where id=?) and menuid='2010'";
        String area = jdbcTemplate.queryForObject(sql, String.class, HeaderContext.get().get("userid"));

        String[] split = area.split(",");


//        根据area找到对应的县区
        return jdbcTemplate.queryForObject("select name from zydzn_country where id=?", String.class, split[0]);

    }

}

